package com.syblood.app.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import androidx.annotation.Nullable;

import com.syblood.app.application.AppContext;
import com.syblood.app.constants.Constants;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;

/**
 * 文件与流处理工具类
 * <p/>
 * Created by xw on 2016-8-1.
 */
public class FileUtil {
    private static final String TAG = "wanwan_"+FileUtil.class.getSimpleName();
    public static final String IMESSAGE_VOICE = getExternalStorePath() + "/ylwj_expert/voice";
    public static final String IMESSAGE_IMAGE = getExternalStorePath() + "/ylwj_expert/image";
    public static final String IMESSAGE_FILE = getExternalStorePath() + "/ylwj_expert/file";
    public static final String IMESSAGE_MOVES = getExternalStorePath() + "/ylwj_expert/moves";

    /**
     * 初始化应用文件夹目录
     */
    public static void initFileAccess() {

        File imessageDir = new File(IMESSAGE_VOICE);
        if (!imessageDir.exists()) {
            imessageDir.mkdir();
        }

        File imageDir = new File(IMESSAGE_IMAGE);
        if (!imageDir.exists()) {
            imageDir.mkdir();
        }
        File movesDir = new File(IMESSAGE_MOVES);
        if (!movesDir.exists()) {
            movesDir.mkdirs();
        }

    }

    /**
     * 判断文件是否存在
     *
     * @param filePath 文件路径
     * @return 是否存在
     */
    public static boolean fileIsExists(String filePath) {
        try {
            File f = new File(filePath);
            if (!f.exists()) {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 获取bitmap
     *
     * @param filePath
     * @return
     */
    public static Bitmap getBitmapByPath(String filePath) {
        return getBitmapByPath(filePath, null);
    }

    /**
     * 获取突变通过Path
     *
     * @param filePath
     * @param opts
     * @return
     */
    public static Bitmap getBitmapByPath(String filePath,
                                         BitmapFactory.Options opts) {
        FileInputStream fis = null;
        Bitmap bitmap = null;
        try {
            bitmap = BitmapFactory.decodeFile(filePath, opts);
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        } finally {
            try {
                fis.close();
            } catch (Exception e) {
            }
        }
        return bitmap;
    }

    public static String path2StrByBase64(String path) {
        Bitmap bit = getBitmapByPath(path);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bit.compress(Bitmap.CompressFormat.JPEG, 40, bos);//参数100表示不压缩
        byte[] bytes = bos.toByteArray();
        return Base64.encodeToString(bytes, Base64.DEFAULT);
    }

    /**
     * 图片转为base64
     *
     * @param path       图片路径
     * @param isCompress 是否压缩
     * @return
     */
    public static String path2StrByBase64(String path, boolean isCompress) {
        Bitmap bit = getBitmapByPath(path);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        if (isCompress) {
            bit.compress(Bitmap.CompressFormat.JPEG, 40, bos);
        } else {
            bit.compress(Bitmap.CompressFormat.JPEG, 100, bos);//参数100表示不压缩
        }
        byte[] bytes = bos.toByteArray();
        return Base64.encodeToString(bytes, Base64.DEFAULT);
    }


    /**
     * 图片转为base64
     *
     * @param bit        图片
     * @param isCompress 是否压缩
     * @return
     */
    public static String path2StrByBase64(Bitmap bit, boolean isCompress) {

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        if (isCompress) {
            bit.compress(Bitmap.CompressFormat.JPEG, 40, bos);
        } else {
            bit.compress(Bitmap.CompressFormat.JPEG, 100, bos);//参数100表示不压缩
        }
        byte[] bytes = bos.toByteArray();
        return Base64.encodeToString(bytes, Base64.DEFAULT);
    }


    /**
     * <p>将文件转成base64 字符串</p>
     *
     * @param path 文件路径
     * @return
     * @throws Exception
     */
    public static String encodeBase64File(String path) throws Exception {
        File file = new File(path);
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return Base64.encodeToString(buffer, Base64.DEFAULT);
    }

    /**
     * 是否有外存卡
     *
     * @return
     */
    public static boolean isExistExternalStore() {
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 外置存储卡的路径
     *
     * @return
     */
    public static String getExternalStorePath() {
        if (isExistExternalStore()) {
            return Environment.getExternalStorageDirectory().getAbsolutePath();
        }
        return null;
    }


    /**
     * 获取语音文件存储目录
     *
     * @return
     */
    public static File getVoicePathName() {
        if (!isExistExternalStore()) {

            return null;
        }

        File directory = new File(IMESSAGE_VOICE);
        if (!directory.exists() && !directory.mkdirs()) {
            return null;
        }

        return directory;
    }

    public static String getFileNameFromUrl(String url) {
        if ((url != null) && (url.length() > 0)) {
            int dot = url.lastIndexOf("/");
            if ((dot > -1) && (dot < (url.length() - 1))) {
                return url.substring(dot + 1);
            }
        }
        return "";
    }

    public static String getFileExtensionNameFromUrl(String url) {
        if ((url != null) && (url.length() > 0)) {
            int dot = url.lastIndexOf('.');
            if ((dot > -1) && (dot < (url.length() - 1))) {
                return url.substring(dot + 1);
            }
        }
        return "";
    }

    /**
     * 转换文件大小
     *
     * @param fileS
     * @return
     */
    public static String FormetFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return fileSizeString;
    }

    /**
     * 返回文件名
     *
     * @param uri
     * @return
     */
    public static String getFilename(Uri uri) {
        File file = new File(uri.getPath());
        if (!file.exists()) {
            return "";
        }
        return file.getName();
    }

    /**
     * Java文件操作 获取文件扩展名
     * Get the file extension, if no extension or file name
     */
    public static String getExtensionName(Uri uri) {
        String filename = uri.getPath();
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot > -1) && (dot < (filename.length() - 1))) {
                return filename.substring(dot + 1);
            }
        }
        return "";
    }

    /**
     * 返回图片存放目录
     *
     * @return
     */
    public static File getImagePathName() {
        if (!isExistExternalStore()) {


            return null;
        }

        File directory = new File(IMESSAGE_IMAGE);
        if (!directory.exists() && !directory.mkdirs()) {

            return null;
        }

        return directory;
    }


    /**
     * 返回文件存放目录
     *
     * @return
     */
    public static File getFilePathName() {
        if (!isExistExternalStore()) {

            return null;
        }

        File directory = new File(IMESSAGE_FILE);
        if (!directory.exists() && !directory.mkdirs()) {

            return null;
        }

        return directory;
    }

    /**
     * 返回拍摄视频存放目录
     *
     * @return
     */
    public static File getMovesPathName() {
        if (!isExistExternalStore()) {

            return null;
        }

        File directory = new File(IMESSAGE_MOVES);
        if (!directory.exists() && !directory.mkdirs()) {

            return null;
        }

        return directory;
    }

    /**
     * byte(字节)根据长度转成kb(千字节)和mb(兆字节)
     *
     * @param bytes
     * @return
     */
    public static String bytes2kb(long bytes) {
        BigDecimal filesize = new BigDecimal(bytes);
        BigDecimal megabyte = new BigDecimal(1024 * 1024);
        float returnValue = filesize.divide(megabyte, 2, BigDecimal.ROUND_UP)
                .floatValue();
        if (returnValue > 1)
            return (returnValue + "MB");
        BigDecimal kilobyte = new BigDecimal(1024);
        returnValue = filesize.divide(kilobyte, 2, BigDecimal.ROUND_UP)
                .floatValue();
        return (returnValue + "KB");
    }

    private final static String FILE_SEP = "/";

    /**
     * 将内容写如文件中
     *
     * @param filePath 文件路径
     * @param content  代写入内容
     * @return true/false
     */
    public static boolean writeFileByStream(String filePath, String content) {
        if (!isFileExists(filePath)) {
            createFile(filePath);
        }

        FileOutputStream outStream = null;
        try {
            outStream = new FileOutputStream(filePath);
            outStream.write(content.getBytes());
            outStream.close();
            return true;
        } catch (IOException e) {
            Log.w(TAG, e.toString());
            return false;
        } finally {
            try {
                if (outStream != null) {
                    outStream.close();
                }
            } catch (IOException e) {
                Log.w(TAG, e.toString());
            }
        }
    }

    /**
     * 将内容写如文件中
     *
     * @param folder  文件夹路径
     * @param file    文件路径
     * @param content 代写入内容
     * @return true/false
     */
    public static boolean writeFile(String folder, String file, String content) {
        return writeFile(folder, file, content, false);
    }

    /**
     * 将内容写如文件中
     *
     * @param folder   文件夹路径
     * @param file     文件路径
     * @param content  代写入内容
     * @param override 是否覆盖写
     * @return true/false
     */
    public static boolean writeFile(String folder, String file, String content, boolean override) {

        if (!isFolderExists(folder)) {
            createFolder(folder);
        }

        String path = folder + FILE_SEP + file;
        if (!isFileExists(path)) {
            createFile(path);
        }

        FileWriter writer = null;
        try {
            //第二个参数为true是追加内容，false是覆盖
            writer = new FileWriter(path, override);
            writer.write(content);
            if (override) {
                writer.write("\r\n");//换行
            }
            return true;
        } catch (IOException e) {
            Log.w(TAG, e.toString());
            return false;
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                Log.w(TAG, e.toString());
            }
        }
    }

    /**
     * 从指定路径读取文件内容
     *
     * @param filePath 待读内容的文件路径
     * @return 文件内容
     */
    @Nullable
    public static String readFile(String filePath) {
        if (!isFileExists(filePath)) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        FileInputStream inputStream = null;
        try {
            //打开文件输入流
            inputStream = new FileInputStream(filePath);

            byte[] buffer = new byte[1024];
            int len = inputStream.read(buffer);
            //读取文件内容
            while (len > 0) {
                sb.append(new String(buffer, 0, len));

                //继续将数据放到buffer中
                len = inputStream.read(buffer);
            }
            //关闭输入流
            inputStream.close();
        } catch (IOException e) {
            Log.w(TAG, e.toString());
            return null;
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                Log.w(TAG, e.toString());
            }
        }
        return sb.toString();
    }

    public static boolean createFile(String folderName, String fileName) {
        String path = folderName + "/" + fileName;
        try {
            if (createFolder(folderName)) {
                File filePath = new File(path);
                if (!filePath.exists()) {
                    return filePath.createNewFile();
                }
                return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 创建指定文件
     *
     * @param filePath 文件绝对路径
     * @return true/false
     */
    private static boolean createFile(String filePath) {
        //传入路径 + 文件名
        File mFile = new File(filePath);
        //判断文件是否存在，存在就即返回true
        if (mFile.exists()) {
            //mFile.delete();
            return true;
        }
        try {
            //创建文件
            return mFile.createNewFile();
        } catch (IOException e) {
            Log.w(TAG, e.toString());
            return false;
        }
    }

    /**
     * 删除指定文件
     *
     * @param filePath 文件绝对路径
     */
    private static boolean deleteFile(String filePath) {
        if (TextUtils.isEmpty(filePath)) {
            return false;
        }

        //传入路径 + 文件名
        File file = new File(filePath);
        //判断文件是否存在
        if (file.exists()) {
            return file.delete();
        }

        return false;
    }

    /**
     * 删除指定文件
     *
     * @param filePaths 需要被删除的文件列表绝对路径
     * @return true/false
     */
    public static boolean deleteFile(String... filePaths) {
        if (filePaths == null) {
            return false;
        }

        for (String filePath : filePaths) {
            if (!deleteFile(filePath)) {
                Log.e(TAG, "deleteFile filed:" + filePath);
                return false;
            }
        }

        return true;
    }

    /**
     * 创建指定的目录
     *
     * @param folderPath 文件目录路径
     * @return true/false
     */
    public static boolean createFolder(String folderPath) {
        boolean success = false;
        try {
            if (isFolderExists(folderPath)) {
                return true;
            }
            File file = new File(folderPath);
            success = file.mkdirs();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return success;
    }

    //判断指定的文件是否存在
    public static boolean isFileExists(String filePath) {
        try {
            File f = new File(filePath);
            if (!f.exists()) {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    //判断指定的目录是否存在
    public static boolean isFolderExists(String folderPath) {
        try {
            File f = new File(folderPath);
            if (!f.exists()) {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 获取文件扩展名
     *
     * @param filename 包含后缀名的文件路径，如"*.txt, *.java"
     */
    public static String getExtensionName(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot > -1) && (dot < (filename.length() - 1))) {
                return filename.substring(dot + 1);
            }
        }
        return filename;
    }

    /**
     * 获取不带扩展名的文件名
     *
     * @param filename 不包含后缀名的文件路径
     */
    public static String getFileNameNoEx(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot > -1) && (dot < (filename.length()))) {
                return filename.substring(0, dot);
            }
        }
        return filename;
    }

    /**
     * 获取文件名及后缀
     */
    public static String getFileNameWithSuffix(String path) {
        if (TextUtils.isEmpty(path)) {
            return "";
        }
        int start = path.lastIndexOf("/");
        if (start != -1) {
            return path.substring(start + 1);
        } else {
            return "";
        }
    }

    public static File getRootPathFile() {
//        if (TextUtils.isEmpty(ConfigManager.getInstance().getApplyNo())) {
            return new File(getDCIMPath());
//        } else {
//            return getAppPackageFilePath();
//        }
        //测试用getDCIMPath();正式用 getAppPackageFilePath();

    }

    /**
     * 获取设备内部存储sd卡的路径：
     *
     * @return /storage/emulated/0
     */
    public static String getInternalSdCardPath() {
        return Environment.getExternalStorageDirectory().getAbsolutePath();
    }

    public static String getDCIMPath() {
        String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera";
        if (!FileUtil.isFolderExists(path)) {
            FileUtil.createFolder(path);
        }
        return path;
    }

    /**
     * 该路径会在sd卡下Android/data/路径下创建packagename路径并最终创建一个cahce目录，在删除app时，这个目录也会被删除。
     *
     * @return /storage/emulated/0/Android/data/packagename/cache
     */
    public static String getAppPackageCachePath() {
        return AppContext.context().getExternalCacheDir().getAbsolutePath();
    }

    /**
     * 该路径会在sd卡下Android/data/路径下创建packagename路径并最终创建一个cahce目录，在删除app时，这个目录也会被删除。
     *
     * @return /storage/emulated/0/Android/data/packagename/files
     */
    public static File getAppPackageFilePath() {
        return AppContext.context().getExternalFilesDir(null);
    }

    public static String getCameraPath() {
        String path = AppContext.context().getExternalCacheDir().getAbsolutePath() + "/picture";
        if (!isFolderExists(path)) {
            createFolder(path);
        }
        return path;
    }

    public static File getPictureFile() {
        String picName = (TextUtils.isEmpty(AppUtil.getCurOrderNo()) ? "GS" : AppUtil.getCurOrderNo())
                + "_" + Constants.IMAGE_TYPE + "_" + AppUtil.getCurrentDate() + Constants.SUFFIX_IMAGE;
        return new File(getRootPathFile(), picName);
    }

    public static String getFileName(String path) {
        int start = path.lastIndexOf(File.separator);
        int end = path.lastIndexOf(".");
        if (start != -1 && end != -1) {
            return path.substring(start + 1, end);
        } else {
            return null;
        }
    }

    public static String getVideoFilePath() {
        return getRootPathFile().getAbsolutePath() + "/"
                + (TextUtils.isEmpty(AppUtil.getCurOrderNo()) ? "GS" : AppUtil.getCurOrderNo())
                + "_" + Constants.VIDEO_TYPE + "_" + AppUtil.getCurrentDate() + Constants.SUFFIX_VIDEO;
    }


    public static byte[] getBytesByFile(String pathStr) {
        File file = new File(pathStr);
        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            byte[] data = bos.toByteArray();
            bos.close();
            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static boolean getFileByBytes(byte[] bytes, String filePath) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            file = new File(filePath);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

}
